package vg.modules.filter;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import vg.services.data_base_manager.data.header.AttributeHeader;
import vg.services.data_base_manager.interfaces.IModel;
import vg.services.data_base_manager.realization.DataBaseFields;
import vg.services.main_manager.MainManager;
import vg.services.user_interface_manager.additional_swing_components.conditionPanel.data.AConditionData;
import vg.services.user_interface_manager.additional_swing_components.conditionPanel.data.ConditionalPanelData;
import vg.services.user_interface_manager.additional_swing_components.conditionPanel.data.GeneralConditionData;

/**
 * This class works with database and so has dependency code.
 * If structure of database in project Visual Graph will changes that 
 * developers must change requests in this class.
 * @author tzolotuhin
 */
public class DataBaseWorker4Filter {
	public static Set<Integer> get_vertex_ids(ConditionalPanelData data, IModel model, int graphId) {
		if(data == null || model == null) return null;

		// build request
		String request = "SELECT distinct v." + DataBaseFields.VERTEX_TABLE_ID + 
						 " FROM " + DataBaseFields.VERTEX_TABLE + " v " + 
						 " WHERE " + "v." + DataBaseFields.VERTEX_TABLE_GRAPH_ID + "=" + graphId;
		if(data.conditions.size() > 0)
			request += " and ( ";
		int i = 0;
		for(AConditionData buf : data.conditions) {
			request += " v." + DataBaseFields.EDGE_TABLE_ID + " in (" + 
					   "SELECT a." + DataBaseFields.ATTRIBUTE_TABLE_OWNER_ID +
					   " FROM " + DataBaseFields.ATTRIBUTE_TABLE + " a " +
					   " WHERE " + "a." + DataBaseFields.ATTRIBUTE_TABLE_OWNER_TYPE + "=" + AttributeHeader.DEF_VERTEX_OWNER_TYPE + " and " +
					   			   "a." + DataBaseFields.ATTRIBUTE_TABLE_OWNER_ID + "=" + "v." + DataBaseFields.VERTEX_TABLE_ID + " and " + 
					   			   "a." + DataBaseFields.ATTRIBUTE_TABLE_NAME + "='";
			switch(buf.type) {
				case AConditionData.DEF_GENERAL_CONDITION:
				default: {
					GeneralConditionData gen_cond = (GeneralConditionData)buf;
					request += gen_cond.name + "' and a." + DataBaseFields.ATTRIBUTE_TABLE_VALUE + " LIKE '%" + gen_cond.value + "%') ";
				}
			}

			if(i < data.operators.size()) {
				request += data.operators.get(i).operator;
			}
			i++;
		}
		
		if(data.conditions.size() > 0)
			request += ");";
		else
			request += "; ";
		
		// execute request
		List<List<Object>> result = model.executeSQLRequest(request.toString());
		if (result != null) {
			Set<Integer> result_vertices = new HashSet<Integer>();
			for (List<Object> row : result) {
				Integer id = (Integer) row.get(0);
				result_vertices.add(id);
			}
			return (result_vertices);
		} else {
			MainManager.windowMessage.errorMessage("Can't execute SQL request.", "Filter panel error");
			return null;
		}
	}
	
	public static Set<Integer> get_edge_ids(ConditionalPanelData data, IModel model, int graphId) {
		if(data == null || model == null) return null;

		// build request
		String request = "SELECT distinct e." + DataBaseFields.EDGE_TABLE_ID + 
						 " FROM " + DataBaseFields.EDGE_TABLE + " e " + 
						 " WHERE " + "e." + DataBaseFields.EDGE_TABLE_GRAPH_ID + "=" + graphId;
		if(data.conditions.size() > 0)
			request += " and ( ";
		int i = 0;
		for(AConditionData buf : data.conditions) {
			request += " e." + DataBaseFields.EDGE_TABLE_ID + " in (" + 
					   "SELECT a." + DataBaseFields.ATTRIBUTE_TABLE_OWNER_ID +
					   " FROM " + DataBaseFields.ATTRIBUTE_TABLE + " a " +
					   " WHERE " + "a." + DataBaseFields.ATTRIBUTE_TABLE_OWNER_TYPE + "=" + AttributeHeader.DEF_EDGE_OWNER_TYPE + " and " +
					   			   "a." + DataBaseFields.ATTRIBUTE_TABLE_OWNER_ID + "=" + "e." + DataBaseFields.EDGE_TABLE_ID + " and " + 
					   			   "a." + DataBaseFields.ATTRIBUTE_TABLE_NAME + "='";
			switch(buf.type) {
				case AConditionData.DEF_GENERAL_CONDITION:
				default: {
					GeneralConditionData gen_cond = (GeneralConditionData)buf;
					request += gen_cond.name + "' and a." + DataBaseFields.ATTRIBUTE_TABLE_VALUE + " LIKE '%" + gen_cond.value + "%') ";
				}
			}

			if(i < data.operators.size()) {
				request += data.operators.get(i).operator;
			}
			i++;
		}
		
		if(data.conditions.size() > 0)
			request += ");";
		else
			request += "; ";
		
		// execute request
		List<List<Object>> result = model.executeSQLRequest(request.toString());
		if (result != null) {
			Set<Integer> result_edges = new HashSet<Integer>();
			for (List<Object> row : result) {
				Integer id = (Integer) row.get(0);
				result_edges.add(id);
			}
			return (result_edges);
		} else {
			MainManager.windowMessage.errorMessage("Can't execute SQL request.", "Filter panel error");
			return null;
		}
	}
}
